﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI;
using System.Web.Mvc;
using System.Web.Routing;
using CAF.Infrastructure.Core;
using CAF.WebSite.Application.WebUI.Mvc;


namespace CAF.WebSite.Application.WebUI
{

    public class TabStripRenderer : ComponentRenderer<TabStrip>
    {

        public TabStripRenderer()
        {
        }

        protected override void WriteHtmlCore(HtmlTextWriter writer)
        {
            var tab = base.Component;
            var hasContent = tab.Items.Any(x => x.Content != null || x.Ajax);
            var isTabbable = tab.Position != TabsPosition.Top;
            var urlHelper = new UrlHelper(this.ViewContext.RequestContext);

            if (tab.Items.Count == 0)
                return;



            tab.HtmlAttributes.AppendCssClass("tabbable");

            if (isTabbable)
            {
                // tab.HtmlAttributes.AppendCssClass("tabs-{0}".FormatInvariant(tab.Position.ToString().ToLower()));
            }

            if (tab.SmartTabSelection)
            {
                tab.HtmlAttributes.AppendCssClass("tabs-autoselect");
                tab.HtmlAttributes.Add("data-tabselector-href", urlHelper.Action("SetSelectedTab", "Common", new { area = "admin" }));
            }

            if (tab.OnAjaxBegin.HasValue())
            {
                tab.HtmlAttributes.Add("data-ajax-onbegin", tab.OnAjaxBegin);
            }

            if (tab.OnAjaxSuccess.HasValue())
            {
                tab.HtmlAttributes.Add("data-ajax-onsuccess", tab.OnAjaxSuccess);
            }

            if (tab.OnAjaxFailure.HasValue())
            {
                tab.HtmlAttributes.Add("data-ajax-onfailure", tab.OnAjaxFailure);
            }

            if (tab.OnAjaxComplete.HasValue())
            {
                tab.HtmlAttributes.Add("data-ajax-oncomplete", tab.OnAjaxComplete);
            }

            writer.AddAttributes(tab.HtmlAttributes);

            writer.RenderBeginTag("div"); // root div
            {
                if (tab.Position == TabsPosition.Below && hasContent)
                    RenderTabContent(writer);

                //div



                // Tabs
                var ulAttrs = new Dictionary<string, object>();
                if (isTabbable)
                {
                    writer.AddAttribute("class", "col-md-2 col-sm-2 col-xs-2");
                    writer.RenderBeginTag("div"); // root div
                    ulAttrs.AppendCssClass("nav nav-{0} tabs-{1}".FormatInvariant(tab.Style.ToString().ToLower(), tab.Position.ToString().ToLower()));
                }
                else
                {
                    ulAttrs.AppendCssClass("nav nav-{0}".FormatInvariant(tab.Style.ToString().ToLower()));
                }
                if (tab.Stacked)
                {
                    ulAttrs.AppendCssClass("nav-stacked");
                }
                writer.AddAttributes(ulAttrs);

                string selector = null;
                var loadedTabs = new List<string>();
                writer.RenderBeginTag("ul");
                {
                    // enable smart tab selection
                    if (tab.SmartTabSelection)
                    {
                        selector = TrySelectRememberedTab();
                    }

                    int i = 1;
                    foreach (var item in tab.Items)
                    {
                        var loadedTabName = this.RenderItemLink(writer, item, i);
                        if (loadedTabName.HasValue())
                        {
                            loadedTabs.Add(loadedTabName);
                        }
                        i++;
                    }

                    writer.RenderEndTag(); // ul
                }
                if (isTabbable)
                {
                    writer.RenderEndTag();//col-md-3 col-sm-3 col-xs-3
                }
                if (tab.Position != TabsPosition.Below && hasContent)
                    RenderTabContent(writer);

                if (selector != null)
                {
                    writer.WriteLine(
@"<script>
	$(function() {{
		_.delay(function() {{
			$('{0}').trigger('show');
		}}, 100);
	}})
</script>".FormatInvariant(selector));
                }

                if (loadedTabs.Count > 0)
                {
                    foreach (var tabName in loadedTabs)
                    {
                        writer.WriteLine("<input type='hidden' class='loaded-tab-name' name='LoadedTabs' value='{0}' />", tabName);
                    }
                }


                writer.RenderEndTag(); // div.tabbable    
            }

        }

        // returns a query selector
        private string TrySelectRememberedTab()
        {
            var tab = this.Component;

            if (tab.Id.IsEmpty())
                return null;

            var model = ViewContext.ViewData.Model as EntityModelBase;
            if (model != null && model.Id == 0)
            {
                // it's a "create" operation: don't select
                return null;
            }

            var rememberedTab = (SelectedTabInfo)ViewContext.TempData["SelectedTab." + tab.Id];
            if (rememberedTab != null && rememberedTab.Path.Equals(ViewContext.HttpContext.Request.RawUrl, StringComparison.OrdinalIgnoreCase))
            {
                // get tab to select
                var tabToSelect = GetTabById(rememberedTab.TabId);

                if (tabToSelect != null)
                {
                    // unselect former selected tab(s)
                    tab.Items.Each(x => x.Selected = false);

                    // select the new tab
                    tabToSelect.Selected = true;

                    // persist again for the next request
                    ViewContext.TempData["SelectedTab." + tab.Id] = rememberedTab;

                    if (tabToSelect.Ajax && tabToSelect.Content == null)
                    {
                        return ".nav a[data-ajax-url][href=#{0}]".FormatInvariant(rememberedTab.TabId);
                    }
                }
            }

            return null;
        }

        private Tab GetTabById(string tabId)
        {
            int i = 1;
            foreach (var item in Component.Items)
            {
                var id = BuildItemId(item, i);
                if (id == tabId)
                {
                    if (!item.Visible || !item.Enabled)
                        break;

                    return item;
                }
                i++;
            }

            return null;
        }

        protected virtual void RenderTabContent(HtmlTextWriter writer)
        {
            var tab = base.Component;
            var isTabbable = tab.Position != TabsPosition.Top;
            if (isTabbable)
            {
                writer.AddAttribute("class", "col-md-10 col-sm-10 col-xs-10");
                writer.RenderBeginTag("div");
            }
            writer.AddAttribute("class", "tab-content");
            writer.RenderBeginTag("div");
            int i = 1;
            foreach (var item in tab.Items)
            {
                this.RenderItemContent(writer, item, i);
                i++;
            }
            writer.RenderEndTag(); // div 
            if (isTabbable)
            {
                writer.RenderEndTag(); // div col-md-9 col-sm-9 col-xs-9
            }
        }

        protected virtual string RenderItemLink(HtmlTextWriter writer, Tab item, int index)
        {
            string temp = "";
            string loadedTabName = null;

            // <li [class="active [hide]"]><a href="#{id}" data-toggle="tab">{text}</a></li>
            if (item.Selected)
            {
                item.HtmlAttributes.AppendCssClass("active");
            }
            else
            {
                if (!item.Visible)
                {
                    item.HtmlAttributes.AppendCssClass("hide");
                }
            }

            if (item.Pull == TabPull.Right)
            {
                item.HtmlAttributes.AppendCssClass("pull-right");
            }

            writer.AddAttributes(item.HtmlAttributes);

            writer.RenderBeginTag("li");
            {
                var itemId = "#" + BuildItemId(item, index);

                if (item.Content != null)
                {
                    writer.AddAttribute("href", itemId);
                    writer.AddAttribute("data-toggle", "tab");
                    writer.AddAttribute("data-loaded", "true");
                    loadedTabName = GetTabName(item) ?? itemId;
                }
                else
                {
                    // no content, create real link instead
                    var url = item.GenerateUrl(base.ViewContext.RequestContext).NullEmpty();

                    if (url == null)
                    {
                        writer.AddAttribute("href", "#");
                    }
                    else
                    {
                        if (item.Ajax)
                        {
                            writer.AddAttribute("href", itemId);
                            writer.AddAttribute("data-ajax-url", url);
                            writer.AddAttribute("data-toggle", "tab");
                        }
                        else
                        {
                            writer.AddAttribute("href", url);
                        }
                    }
                }

                if (item.BadgeText.HasValue())
                {
                    item.LinkHtmlAttributes.AppendCssClass("clearfix");
                }

                writer.AddAttributes(item.LinkHtmlAttributes);
                writer.RenderBeginTag("a");
                {
                    // Tab Icon
                    if (item.Icon.HasValue())
                    {
                        writer.AddAttribute("class", item.Icon);
                        writer.RenderBeginTag("i");
                        writer.RenderEndTag(); // i
                    }
                    else if (item.ImageUrl.HasValue())
                    {
                        var url = new UrlHelper(this.ViewContext.RequestContext);
                        writer.AddAttribute("src", url.Content(item.ImageUrl));
                        writer.AddAttribute("alt", "Icon");
                        writer.RenderBeginTag("img");
                        writer.RenderEndTag(); // img
                    }
                    //writer.WriteEncodedText(item.Text);

                    // Badge
                    if (item.BadgeText.HasValue())
                    {
                        //writer.Write("&nbsp;");

                        // caption
                        writer.AddAttribute("class", "tab-caption");
                        writer.RenderBeginTag("span");
                        writer.WriteEncodedText(item.Text);
                        writer.RenderEndTag(); // span > badge

                        // label
                        temp = "label";
                        if (item.BadgeStyle != BadgeStyle.Default)
                        {
                            temp += " label-" + item.BadgeStyle.ToString().ToLower();
                        }
                        if (base.Component.Position == TabsPosition.Left)
                        {
                            temp += " pull-right"; // looks nicer 
                        }
                        writer.AddAttribute("class", temp);
                        writer.RenderBeginTag("span");
                        writer.WriteEncodedText(item.BadgeText);
                        writer.RenderEndTag(); // span > badge
                    }
                    else
                    {
                        writer.WriteEncodedText(item.Text);
                    }
                    writer.RenderEndTag(); // a
                }
                writer.RenderEndTag(); // li
            }

            return loadedTabName;
        }

        private string GetTabName(Tab tab)
        {
            object value;
            if (tab.LinkHtmlAttributes.TryGetValue("data-tab-name", out value))
            {
                return value.ToString();
            }
            return null;
        }

        protected virtual void RenderItemContent(HtmlTextWriter writer, Tab item, int index)
        {
            // <div class="tab-pane fade in [active]" id="{id}">{content}</div>
            item.ContentHtmlAttributes.AppendCssClass("tab-pane");
            if (base.Component.Fade)
            {
                item.ContentHtmlAttributes.AppendCssClass("fade");
            }
            if (item.Selected)
            {
                if (base.Component.Fade)
                {
                    item.ContentHtmlAttributes.AppendCssClass("in");
                }
                item.ContentHtmlAttributes.AppendCssClass("active");
            }
            writer.AddAttributes(item.ContentHtmlAttributes);
            writer.AddAttribute("id", BuildItemId(item, index));
            writer.RenderBeginTag("div");
            {
                if (item.Content != null)
                {
                    writer.WriteLine(item.Content.ToHtmlString());
                }
            }
            writer.RenderEndTag(); // div
        }

        private string BuildItemId(Tab item, int index)
        {
            if (item.Name.HasValue())
            {
                return item.Name;
            }
            return "{0}-{1}".FormatInvariant(this.Component.Id, index);
        }


    }

}
